import { MessageStatus } from "@/types/chat-message";
import { MessageOperation } from "@/types/stomp";
import CurrentUserIdManager from "@/utils/user-utils";
import NotificationFunctions from "@/notification";
import ChatMessageStateStore from "@/store/chat-message";
import ChatSessionStateStore from "@/store/chat-session";
import {
  updateChatMessage,
  insertChatMessage,
} from "@/services/sqlite/chat-message";
import {
  getSessionBySessionId,
  updateChatSession,
  insertChatSession,
} from "@/services/sqlite/chat-session";
import { extractLastMessageText } from "@/utils/message-utils";
import ChatDetailPageStore from "@/store/chat-detail-page";
import { ChatOfflineMessage, ChatReceivedMessage } from "@/types/stomp/chat";
import { IMessage } from "@stomp/stompjs";
import { OnlineSystemMessage } from "@/types/stomp/system";
import * as FileSystem from "expo-file-system";
import {USER_DATA_SAVE_PATH_PREFIX} from "@/constants/storage";
import {
  createFileCache,
  getFileCacheByMd5,
} from "@/services/sqlite/file-cache";
import { FileType } from "@/types/file-upload";
import {
  getUserProfileById, insertUserProfile,
  updateUserProfile,
} from "@/services/sqlite/chat-user";

const { pushNotification } = NotificationFunctions;

class AsyncQueue {
  private queue: (() => Promise<void>)[] = [];
  private running = false;

  add(task: () => Promise<void>) {
    this.queue.push(task);
    this.runNext();
  }

  private async runNext() {
    if (this.running || this.queue.length === 0) return;
    this.running = true;

    const next = this.queue.shift();
    if (next) {
      try {
        await next();
      } catch (e) {
        console.error("AsyncQueue task error:", e);
      }
    }

    this.running = false;
    this.runNext();
  }
}

const dbQueue = new AsyncQueue();

// 策略接口
interface MessageOperationStrategy {
  execute(imessage: IMessage): void;
}

//处理媒体消息
async function handleMediaMessage(message: ChatReceivedMessage): Promise<void> {
  // 映射消息类型到文件类型
  const fileTypeMap = {
    1: FileType.IMAGE,
    2: FileType.FILE,
    3: FileType.VIDEO,
    4: FileType.AUDIO,
    5: FileType.AUDIO,
  };
  const { messageType, content } = message;
  // 快速检查是否为媒体类型
  if (![1, 2, 3, 4, 5].includes(messageType)) return;

  try {
    const parsedContent =
      typeof content === "string" ? JSON.parse(content) : content;
    if (!parsedContent.fileUrl) return;

    // 计算文件唯一标识
    const fileMd5 =
      parsedContent.fileId || parsedContent.md5 || Date.now().toString();

    // 检查文件是否已缓存
    const existingCache = await getFileCacheByMd5(fileMd5);
    if (existingCache) return;

    // 创建缓存目录并下载文件
    const fileDir = `${USER_DATA_SAVE_PATH_PREFIX}cache/media/${messageType}`;
    await FileSystem.makeDirectoryAsync(fileDir, { intermediates: true });

    const fileExt = parsedContent.fileUrl.split(".").pop() || "dat";
    const localFilePath = `${fileDir}/${fileMd5}.${fileExt}`;

    const downloadResult = await FileSystem.downloadAsync(
      parsedContent.fileUrl,
      localFilePath
    );

    if (downloadResult.status === 200) {
      const fileInfoResult = await FileSystem.getInfoAsync(localFilePath, {
        size: true,
      });

      // 缓存文件信息
      await createFileCache({
        filePath: localFilePath,
        serverUrl: parsedContent.fileUrl,
        fileMd5: fileMd5,
        fileType: messageType,
        fileSize:
          fileInfoResult.exists && "size" in fileInfoResult
            ? fileInfoResult.size
            : 0,
        optional: {
          ...(parsedContent.fileInfo || {}),
          fileTypeStr: fileTypeMap[messageType], // 使用映射的字符串文件类型
        },
        createTime: Date.now(),
      });
    }
  } catch (error) {
    console.error("媒体消息处理失败:", error);
  }
}

// 处理用户信息更新
async function handleUserInfoUpdate(
  message: ChatReceivedMessage
): Promise<void> {
  const { user } = message;
  if (!user?.id) return;

  try {
    const existingUser = await getUserProfileById(user.id);

    // 用户存在且需要更新
    if (
      existingUser &&
      user.updateTime &&
      existingUser.updateTime < user.updateTime
    ) {
      await updateUserProfile(existingUser, {
        id: user.id,
        name: user.name,
        avatar: user.avatar,
        updateTime: user.updateTime,
      });
    }
    // 用户不存在，可能需要创建
    else if (!existingUser) {
      console.log(`接收到未知用户(${user.id})消息，需要创建用户资料`);
      // 这里可以添加创建用户资料的逻辑
      await insertUserProfile({
        id: user.id,
        name: user.name,
        avatar: user.avatar,
        updateTime: user.updateTime,
      })
    }
  } catch (error) {
    console.error("用户信息更新处理失败:", error);
  }
}

// 处理群聊信息更新
async function handleGroupInfoUpdate(
  message: ChatReceivedMessage
): Promise<void> {
  // 只处理群聊消息
  if (message.sessionType !== 1) return;
  try {
    const { content, sessionId } = message;
    const parsedContent =
      typeof content === "string" ? JSON.parse(content) : content;
    // 检查消息中是否包含群聊信息
    if (parsedContent?.groupInfo) {
      const groupInfo = parsedContent.groupInfo;
      //todo
    }
  } catch (error) {
    console.error("群聊信息更新处理失败:", error);
  }
}

// 接收消息策略
class ReceiveMessageStrategy implements MessageOperationStrategy {
  private messageStoreActions = ChatMessageStateStore.getState().actions;
  private sessionStoreActions = ChatSessionStateStore.getState().actions;
  private chatDetailStoreState = ChatDetailPageStore.getState().state;

  execute(imessage: IMessage): void {
    const message = JSON.parse(imessage.body) as ChatReceivedMessage;
    const ownerId = CurrentUserIdManager.getUserId();
    // 插入聊天消息
    dbQueue.add(async () => {
      //媒体消息处理
      await handleMediaMessage(message);
      //用户信息更新处理
      await handleUserInfoUpdate(message);
      //群聊信息更新处理
      await handleGroupInfoUpdate(message);
      if (this.chatDetailStoreState.session.sessionId === message.sessionId) {
        this.messageStoreActions.addMessage(message);
      }
      await insertChatMessage({ ownerId, ...message });
    });

    // 更新会话
    dbQueue.add(async () => {
      const lastMessage = extractLastMessageText(
        message.messageType,
        message.content
      );
      let session = await getSessionBySessionId({
        ownerId,
        sessionId: message.sessionId,
      });
      if (!session) {
        // 如果会话不存在，则创建一个新的会话
        await insertChatSession({
          ownerId,
          sessionId: message.sessionId,
          sessionType: message.sessionType,
        });
      }
       session = await getSessionBySessionId({
        ownerId,
        sessionId: message.sessionId,
      });

      const isCurrentSession = this.chatDetailStoreState.session === null ? false : this.chatDetailStoreState.session.sessionId === message.sessionId;
      const updatedSession = {
        ownerId,
        sessionId: message.sessionId,
        lastMessageId: message.messageId,
        lastMessage,
        unreadCount: !isCurrentSession
          ? session.unreadCount + 1
          : session.unreadCount, // 如果会话存在，更新最后一条消息
      };
      await updateChatSession(updatedSession);
      if (!isCurrentSession) {
        // 如果当前会话是不是接收的消息所在的会话
        this.sessionStoreActions.updateSession(updatedSession);
        // 发布通知
        await pushNotification({
          title: message.user.name,
          body: lastMessage,
          data: {
            senderId: message.user.id,
            sessionId: message.sessionId,
          },
        });
        await updateChatSession(updatedSession);
      }
    });
  }
}

// 离线消息策略
class OfflineMessageStrategy implements MessageOperationStrategy {
  private messageStoreActions = ChatMessageStateStore.getState().actions;
  private sessionStoreActions = ChatSessionStateStore.getState().actions;
  private chatDetailStoreState = ChatDetailPageStore.getState().state;

  execute(imessage: IMessage): void {
    const ownerId = CurrentUserIdManager.getUserId();
    const offlineMessage: ChatOfflineMessage = JSON.parse(
      imessage.body
    ) as ChatOfflineMessage;
    const messages: ChatReceivedMessage[] = offlineMessage.content;
    dbQueue.add(async () => {
      // 批量插入离线消息
      for (const message of messages) {
        //媒体消息处理
        await handleMediaMessage(message);
        await insertChatMessage({ ownerId, ...message });
      }

      // 分组会话
      const groupedMessages = messages.reduce((groups, message) => {
        const sessionId = message.sessionId;
        if (!groups[sessionId]) {
          groups[sessionId] = [];
        }
        groups[sessionId].push(message);
        return groups;
      }, {} as Record<string, ChatReceivedMessage[]>);
      // 根据当前预览的会话更新未读数和插入消息
      // 对每组消息按发送顺序排序
      // Object.values(groupedMessages).forEach(group => {
      //     group.sort((a, b) => a.createTime - b.createTime);
      // });
      // 遍历每个会话组的会话
      for (const sessionId in groupedMessages) {
        const currentSessionMessages = groupedMessages[sessionId];
        const session = await getSessionBySessionId({ ownerId, sessionId });
        if (!session) {
          // 如果会话不存在，则创建一个新的会话
          await insertChatSession({
            ownerId,
            sessionId,
            sessionType: currentSessionMessages[0].sessionType,
          });
        }

        //用户信息更新处理
        for (const message of currentSessionMessages) {
          await handleUserInfoUpdate(message);
        }

        //群聊信息更新处理
        if (currentSessionMessages[0].sessionType === 1) {
          // 如果是群聊
          for (const message of currentSessionMessages) {
            await handleGroupInfoUpdate(message);
          }
        }

        // 更新会话的最后一条消息和未读数
        const lastMessage = extractLastMessageText(
          currentSessionMessages[0].messageType,
          currentSessionMessages[0].content
        );
        const updateData = {
          ownerId,
          sessionId,
          lastMessageId: currentSessionMessages[0].messageId,
          lastMessage,
          unreadCount:
            this.chatDetailStoreState.session.sessionId === sessionId
              ? session.unreadCount || 0
              : (session.unreadCount || 0) + currentSessionMessages.length,
        };
        this.sessionStoreActions.updateSession(updateData);
        await updateChatSession(updateData);
        if (this.chatDetailStoreState.session.sessionId === sessionId) {
          this.messageStoreActions.addBatchMessages(currentSessionMessages);
        }
      }
    });
  }
}

// 确认发送消息策略
class SentMessageStrategy implements MessageOperationStrategy {
  private messageStoreActions = ChatMessageStateStore.getState().actions;

  execute(imessage: IMessage): void {
    const message = JSON.parse(imessage.body) as OnlineSystemMessage;
    const ownerId = CurrentUserIdManager.getUserId();
    dbQueue.add(async () => {
      const updateData = {
        messageId: message.messageId,
        ownerId,
        status: MessageStatus.SENT,
      };
      this.messageStoreActions.updateMessage(updateData);
      await updateChatMessage(updateData);
    });
  }
}

// 撤回消息策略
class RevokeMessageStrategy implements MessageOperationStrategy {
  private messageStoreActions = ChatMessageStateStore.getState().actions;
  private sessionStoreActions = ChatSessionStateStore.getState().actions;

  execute(imessage: IMessage): void {
    const message = JSON.parse(imessage.body) as ChatReceivedMessage;
    const ownerId = CurrentUserIdManager.getUserId();
    // 撤回store数据
    dbQueue.add(async () => {
      const updateData = {
        messageId: message.messageId,
        ownerId: ownerId,
        revokeStatus: true,
      };
      this.messageStoreActions.updateMessage(updateData);
      await updateChatMessage(updateData);
    });
    //撤回sqlite数据
    dbQueue.add(() =>
      updateChatMessage({
        ownerId,
        messageId: message.messageId,
        revokeStatus: true,
      })
    );
    //更新会话（如果该消息为最后一条消息，则更新会话的最后一条消息描述）
    dbQueue.add(async () => {
      const session = await getSessionBySessionId({
        ownerId,
        sessionId: message.sessionId,
      });
      if (session && session.lastMessageId === message.messageId) {
        const updateData = {
          ownerId: ownerId,
          sessionId: message.sessionId,
          lastMessage: `【${
            ownerId === message.user.id ? "我" : "对方"
          }撤回了一条消息】`,
        };
        this.sessionStoreActions.updateSession(updateData);
        await updateChatSession(updateData);
      }
    });
  }
}

// 策略上下文
class MessageOperationContext {
  public getStrategy(operation: MessageOperation): MessageOperationStrategy {
    switch (operation) {
      case MessageOperation.RECEIVE:
        return new ReceiveMessageStrategy();
      case MessageOperation.OFFLINE:
        return new OfflineMessageStrategy();
      case MessageOperation.SENT:
        return new SentMessageStrategy();
      case MessageOperation.REVOKE:
        return new RevokeMessageStrategy();
      default:
        throw new Error(`未知的操作类型: ${operation}`);
    }
  }
}

export default new MessageOperationContext();
